package com.hs.carrental.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hs.carrental.common.SysConstant;
import com.hs.carrental.dto.LoginDto;
import com.hs.carrental.dto.RegisterDto;
import com.hs.carrental.dto.customer.CustomerPageDto;
import com.hs.carrental.dto.customer.CustomerSaveDto;
import com.hs.carrental.dto.customer.GetUserInfoDto;
import com.hs.carrental.dto.customer.UpdatePasswordDto;
import com.hs.carrental.entity.Admin;
import com.hs.carrental.entity.Customer;
import com.hs.carrental.entity.Store;
import com.hs.carrental.mapper.AdminMapper;
import com.hs.carrental.mapper.CustomerMapper;
import com.hs.carrental.mapper.StoreMapper;
import com.hs.carrental.service.ICustomerService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hs.carrental.util.Helper;
import com.hs.carrental.util.JwtUtil;
import com.hs.carrental.util.PasswordEncrypter;
import com.hs.carrental.vo.AdminLoginVo;
import com.hs.carrental.vo.LoginVo;
import com.hs.carrental.vo.UpdatePasswordVo;
import com.hs.carrental.vo.customer.CustomerPageVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.sql.Struct;
import java.time.Duration;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author lyy
 * @since 2021-03-17
 */
@Service
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> implements ICustomerService {

    private final static String TOKEN_PREFIX = "LOGIN_INFO_";

    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private AdminMapper adminMapper;

    @Autowired
    private StoreMapper storeMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public boolean register(RegisterDto registerDto) throws UnsupportedEncodingException {
        Customer customer = new Customer();
        BeanUtils.copyProperties(registerDto,customer);
        //密码加密
        customer.setCustomerPassword(PasswordEncrypter.getEncryptedPwd(registerDto.getCustomerPassword()));
        customer.setCustomerState("0");
        //保存
        boolean save = this.save(customer);
        return save;
    }

    @Override
    public boolean checkUserName(String userName,Integer type) {
        if (type.equals(SysConstant.LOGIN_TYPE_ADMIN)){
            //管理员
            QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("adminAccout",userName);
            List<Admin> admins = adminMapper.selectList(queryWrapper);
            return admins.size() > 0 ? true : false;
        } else {
            QueryWrapper<Customer> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("customerAccount",userName);
            List<Customer> customers = customerMapper.selectList(queryWrapper);
            return customers.size() > 0 ? true : false;
        }
    }

    @Override
    public JSONObject login(LoginDto loginDto) throws Exception {
        if (loginDto.getIdentity().equals(SysConstant.LOGIN_TYPE_ADMIN)){
            //管理员
            QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("adminAccout",loginDto.getUsername());
            Admin admin = adminMapper.selectOne(queryWrapper);
            AdminLoginVo adminLoginVo = new AdminLoginVo();
            BeanUtils.copyProperties(admin,adminLoginVo);
            if (PasswordEncrypter.validPasswd(loginDto.getPassword(),admin.getAdminPassword())){
                //校验通过 成功登陆 生成token
                String token = JwtUtil.createJWT(UUID.randomUUID().toString(), JSON.toJSONString(admin), null);
                adminLoginVo.setToken(token);
//                redisTemplate.opsForValue().set(TOKEN_PREFIX + adminLoginVo.getAdminAccout(), adminLoginVo , Duration.ofHours(1));
            } else {
                // 密码错误
                return null;
            }
            return (JSONObject)JSONObject.toJSON(adminLoginVo);
        } else {
            //普通用户
            QueryWrapper<Customer> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("customerAccount",loginDto.getUsername());
            Customer customer = customerMapper.selectOne(queryWrapper);
            LoginVo loginVo = new LoginVo();
            BeanUtils.copyProperties(customer,loginVo);
            if (PasswordEncrypter.validPasswd(loginDto.getPassword(),customer.getCustomerPassword())){
                //校验通过 成功登陆 生成token
                String token = JwtUtil.createJWT(UUID.randomUUID().toString(), JSON.toJSONString(customer), null);
                loginVo.setToken(token);
//                redisTemplate.opsForValue().set(TOKEN_PREFIX + loginVo.getCustomerAccount(), loginVo , Duration.ofHours(1));
            } else {
                // 密码错误
                return null;
            }
            return (JSONObject)JSONObject.toJSON(loginVo);
        }
    }

    /**
     * 新增编辑客户
     * @param customerSaveDto
     * @return
     */
    @Override
    public boolean save(CustomerSaveDto customerSaveDto) throws UnsupportedEncodingException {
        Customer customer = new Customer();
        //如果密码不为空 加密密码
        if (!Helper.isEmpty(customerSaveDto.getCustomerPassword())){
            customerSaveDto.setCustomerPassword(PasswordEncrypter.getEncryptedPwd(customerSaveDto.getCustomerPassword()));
        }
        BeanUtils.copyProperties(customerSaveDto,customer);
        //新增或更新用户
        boolean saveOrUpdate = this.saveOrUpdate(customer);
        return saveOrUpdate;
    }

    /**
     * 分页
     * @param customerPageDto
     * @return
     */
    @Override
    public IPage<CustomerPageVo> getPage(CustomerPageDto customerPageDto) {
        Page<Customer> page = new Page<>(customerPageDto.getPageNum(),customerPageDto.getPageSize());
        //分页查询
        IPage<CustomerPageVo> iPage = customerMapper.getPage(page, customerPageDto.getCustomerName(), customerPageDto.getCustomerAccount());
        return iPage;
    }

    /**
     * 更新密码
     * @param updatePasswordDto
     * @return
     * @throws Exception
     */
    @Override
    public UpdatePasswordVo updatePassword(UpdatePasswordDto updatePasswordDto) throws Exception {
        UpdatePasswordVo updatePasswordVo = new UpdatePasswordVo();
        if (updatePasswordDto.getIdentity().equals(SysConstant.LOGIN_TYPE_USER)){
            //普通用户
            // 校验旧密码是否正确
            QueryWrapper<Customer> customerQueryWrapper = new QueryWrapper<>();
            customerQueryWrapper.eq("customerAccount",updatePasswordDto.getUserId());
            //根据用户名查询用户
            List<Customer> customers = customerMapper.selectList(customerQueryWrapper);
            Customer customer = new Customer();
            //如果为空 则无该用户
            if (Helper.isEmpty(customers)){
                updatePasswordVo.setMsg("无效的用户id");
                updatePasswordVo.setCode(500);
                return updatePasswordVo;
            }
            //不为空 用户名 唯一 取集合第一个
            customer = customers.get(0);
            //校验旧密码是否正确
            if (!PasswordEncrypter.validPasswd(updatePasswordDto.getOldPassWord(),customer.getCustomerPassword())){
                updatePasswordVo.setMsg("旧密码不正确");
                updatePasswordVo.setCode(500);
                return updatePasswordVo;
            }
            //更新密码
            customer.setCustomerPassword(PasswordEncrypter.getEncryptedPwd(updatePasswordDto.getNewPassWord()));
            //通过主键更新用户信息
            customerMapper.updateById(customer);
        } else if (updatePasswordDto.getIdentity().equals(SysConstant.LOGIN_TYPE_ADMIN)){
            //管理员
            QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("adminAccout",updatePasswordDto.getUserId());
            //根据用户名 查用户
            List<Admin> admins = adminMapper.selectList(queryWrapper);
            Admin admin = new Admin();
            //如果为空 则无该用户
            if (Helper.isEmpty(admin)){
                updatePasswordVo.setMsg("无效的用户id");
                updatePasswordVo.setCode(500);
                return updatePasswordVo;
            }
            admin = admins.get(0);
            //校验旧密码是否正确
            if (!PasswordEncrypter.validPasswd(updatePasswordDto.getOldPassWord(),admin.getAdminPassword())){
                updatePasswordVo.setMsg("旧密码不正确");
                updatePasswordVo.setCode(500);
                return updatePasswordVo;
            }
            //更新密码
            admin.setAdminPassword(PasswordEncrypter.getEncryptedPwd(updatePasswordDto.getNewPassWord()));
            //通过主键更新用户信息
            adminMapper.updateById(admin);
        }
        return updatePasswordVo;
    }

    /**
     * 获取个人信息
     * @param getUserInfoDto
     * @return
     */
    @Override
    public JSONObject getUserInfo(GetUserInfoDto getUserInfoDto) {
        JSONObject jsonObject = new JSONObject();
        if (getUserInfoDto.getIdentity().equals(SysConstant.LOGIN_TYPE_USER)){
            //普通用户
            QueryWrapper<Customer> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("customerAccount",getUserInfoDto.getUserId());
            Customer customer = customerMapper.selectOne(queryWrapper);
            jsonObject = JSONObject.parseObject(JSON.toJSONString(customer, SerializerFeature.WriteMapNullValue));
        } else {
            //管理员
            QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("adminAccout",getUserInfoDto.getUserId());
            Admin admin = adminMapper.selectOne(queryWrapper);
            jsonObject = JSONObject.parseObject(JSON.toJSONString(admin, SerializerFeature.WriteMapNullValue));
        }
        //门店信息
        Store store = storeMapper.selectById(jsonObject.getInteger("storeId"));
        jsonObject.put("storeName",Helper.isEmpty(store)?"":store.getStore());
        return jsonObject;
    }

    /**
     * 修改个人信息
     * @param jsonObject
     * @return
     */
    @Override
    public boolean updateUserInfo(JSONObject jsonObject) {
        Integer identity = jsonObject.getInteger("identity");
        boolean res;
        if (identity.equals(SysConstant.LOGIN_TYPE_ADMIN)){
            //管理员
            Admin admin = JSONObject.parseObject(jsonObject.toJSONString(), Admin.class);
            res = adminMapper.updateById(admin)>0?true:false;
        }else {
            Customer customer = JSONObject.parseObject(jsonObject.toJSONString(), Customer.class);
            res = customerMapper.updateById(customer)>0?true:false;
        }
        return res;
    }
}
